home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / rayshade / libray / libobj / intersect.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  4KB  |  177 lines

  1. /*
  2.  * intersect.c
  3.  *
  4.  * Copyright (C) 1989, 1991, Craig E. Kolb
  5.  * All rights reserved.
  6.  *
  7.  * This software may be freely copied, modified, and redistributed
  8.  * provided that this copyright notice is preserved on all copies.
  9.  *
  10.  * You may not distribute this software, in whole or in part, as part of
  11.  * any commercial product without the express consent of the authors.
  12.  *
  13.  * There is no warranty or other guarantee of fitness of this software
  14.  * for any purpose.  It is provided solely "as is".
  15.  *
  16.  * $Id: intersect.c,v 1.1 1994/05/13 00:14:59 millard Exp millard $
  17.  *
  18.  * $Log: intersect.c,v $
  19.  * Revision 1.1  1994/05/13  00:14:59  millard
  20.  * Initial revision
  21.  *
  22.  * Revision 4.0  91/07/17  14:38:37  kolb
  23.  * Initial version.
  24.  * 
  25.  */
  26. #include "geom.h"
  27.  
  28. static void AddToHitList();
  29. /*
  30.  * Number of bounding volume tests.
  31.  * External modules have read access via IntersectStats().
  32.  */
  33. static unsigned long BVTests;
  34.  
  35. /*
  36.  * Intersect object & ray.  Return distance from "pos" along "ray" to
  37.  * intersection point.  Return value <= 0 indicates no intersection.
  38.  */
  39. int
  40. intersect(obj, ray, hitlist, mindist, maxdist)
  41. Geom *obj;                /* Geom to be tested. */
  42. Ray *ray;                /* Ray origin, direction. */
  43. HitList *hitlist;            /* Intersection path */
  44. Float mindist, *maxdist;
  45. {
  46.     Ray newray;
  47.     Vector vtmp;
  48.     Trans *curtrans;    
  49.     Float distfact, nmindist, nmaxdist;
  50.  
  51.     /*
  52.      * Check ray/bounding volume intersection, if required.
  53.      */
  54.     if (obj->methods->checkbounds) {
  55.         VecAddScaled(ray->pos, mindist, ray->dir, &vtmp);
  56.         if (OutOfBounds(&vtmp, obj->bounds)) {
  57.             nmaxdist = *maxdist;
  58.             BVTests++;
  59.             if (!BoundsIntersect(ray, obj->bounds, mindist,
  60.                             &nmaxdist))
  61.                 return FALSE;
  62.         }
  63.     }
  64.  
  65.     newray = *ray;
  66.     nmindist = mindist;
  67.     nmaxdist = *maxdist;
  68.  
  69.     /*
  70.      * Transform the ray if necessary.
  71.      */
  72.     if (obj->trans != (Trans *)0) {
  73.         /*
  74.          * If object's idea of the current time is wrong,
  75.          * update the transformations.
  76.          */
  77.         if (obj->animtrans && !equal(obj->timenow, ray->time)) {
  78.             TransResolveAssoc(obj->trans);
  79.         }
  80.                 
  81.         /*
  82.          * Transforming the ray can change the distance between
  83.          * the ray origin and the point of intersection.
  84.          * We save the amount the ray is "stretched" and later
  85.          * divide the computed distance by this amount.
  86.          */
  87.         distfact = 1.;
  88.         for (curtrans = obj->transtail; curtrans; 
  89.              curtrans = curtrans->prev)
  90.             distfact *= RayTransform(&newray, &curtrans->itrans);
  91.         nmindist *= distfact;
  92.         nmaxdist *= distfact;
  93.     }
  94.     /*
  95.      * Geom has been updated to current time.
  96.      */
  97.     obj->timenow = ray->time;
  98.  
  99.     /*
  100.      * Call correct intersection routine.
  101.      */
  102.     if (IsAggregate(obj)) {
  103.         /*
  104.          * Aggregate
  105.          */
  106.         if (!(*obj->methods->intersect)
  107.              (obj->obj, &newray, hitlist, nmindist, &nmaxdist))
  108.         return FALSE;
  109.     } else {
  110.         /*
  111.          * Primitive
  112.          */
  113.         if (!(*obj->methods->intersect)
  114.               (obj->obj, &newray, nmindist, &nmaxdist))
  115.             return FALSE;
  116.         hitlist->nodes = 0;
  117.     }
  118.  
  119.     /*
  120.      * Had a hit -- add ray, distance and object to tail of hitlist.
  121.      */
  122.     AddToHitList(hitlist, &newray, nmindist, nmaxdist, obj);
  123.  
  124.     /*
  125.      * Set dist to distance to intersection point from the origin
  126.      * of the untransformed ray.
  127.      */
  128.     if (obj->trans != (Trans *)0)
  129.         *maxdist = nmaxdist / distfact;
  130.     else
  131.         *maxdist = nmaxdist;
  132.  
  133.     return TRUE;
  134. }
  135.  
  136. static void
  137. AddToHitList(hitlist, ray, mind, dist, obj)
  138. HitList *hitlist;
  139. Ray *ray;
  140. Float mind, dist;
  141. Geom *obj;
  142. {
  143.     HitNode *np;
  144.     Trans *list;
  145.  
  146.     np = &hitlist->data[hitlist->nodes++];
  147.  
  148.     np->ray = *ray;
  149.     np->obj = obj;
  150.     np->mindist = mind;
  151.     np->dist = dist;
  152.     np->enter = 0;
  153.  
  154.     if (obj->trans) {
  155.         /*
  156.          * Compute total transformation, forward and inverse,
  157.          * for this object, and store in hitlist for use later.
  158.          */
  159.         TransCopy(obj->trans, &np->trans);
  160.         for (list = obj->trans->next; list; list = list->next)
  161.             TransCompose(&np->trans, list, &np->trans);
  162.         np->dotrans = TRUE;
  163.     } else
  164.         np->dotrans = FALSE;
  165. }
  166.  
  167. /*
  168.  * Return intersection statistics.
  169.  * Currently, this is limited to the # of bounding volume test performed.
  170.  */
  171. void
  172. IntersectStats(bvtests)
  173. unsigned long *bvtests;
  174. {
  175.     *bvtests = BVTests;
  176. }
  177.